package no.nordicsemi.android.nrftoolbox;

import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

public class ReqActivity extends AppCompatActivity {

    List<String> macList = null;
    Integer cursor = 0;
    boolean isConnected = false;
    String targetMac;
    int toNext = 0;
    TextView tv;
    //private Intent gattServiceIntent;

    private BluetoothLeService mBluetoothLeService;

    public static final UUID WRITE_UUID = UUID.fromString("6e400002-b5a3-f393-e0a9-e50e24dcca9e");
    public static final UUID READ_UUID = UUID.fromString("6e400003-b5a3-f393-e0a9-e50e24dcca9e");
    public static final UUID DFU_UUID = UUID.fromString("8ec90003-f315-4f60-9fb8-838830daea50");
    public static final UUID DFU_DESCRIPTOR = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");

    private BluetoothGattCharacteristic writeCh;
    private BluetoothGattCharacteristic readCh;
    private BluetoothGattCharacteristic bootReadCh;
    private BluetoothGattCharacteristic bootWriteCh;
    private BluetoothGattCharacteristic bootNotCh;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_req);
        final Toolbar toolbar  = findViewById(R.id.toolbar_actionbar);
        setSupportActionBar(toolbar);
        Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
        Log.d("ReqActivity", "oncreate, before init()");
        init();
        Log.d("ReqActivity", "oncreate, before bindService");
        Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);
        bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
        tv = (TextView) findViewById(R.id.display_detail);
        findViewById(R.id.start_process).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                tv.setText("");
                Log.d("ReqActivity", "click on start");
                cursor = 0;
                targetMac = macList.get(cursor);
                findViewById(R.id.start_process).setEnabled(false);
                mBluetoothLeService.connect(targetMac);
                tv.append("开始遍历。。。\n");
                tv.append(targetMac + " : 正在连接设备。。。\n");


            }
        });

    };


    private final ServiceConnection mServiceConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder service) {
            mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
            Log.d("mBluetoothLeService", "is null : " + (mBluetoothLeService == null));
            if (!mBluetoothLeService.initialize()) {
                Log.e("DCA_onServCon", "Unable to initialize Bluetooth");
                finish();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            mBluetoothLeService = null;
        }
    };


    // 接收蓝牙连接结果
    private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            Log.d("ACTION", action);
            if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
                isConnected = true;
                updateConnectionState("Connected");
                invalidateOptionsMenu();
                Toast.makeText(ReqActivity.this, "蓝牙连接成功!", Toast.LENGTH_SHORT).show();
                tv.append(targetMac + " : 蓝牙连接成功！\n");
                Log.d("III", "sendMessage(connect success");
            } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
                isConnected = false;
                updateConnectionState("Disconnected");
                Toast.makeText(ReqActivity.this, "蓝牙连接断开!", Toast.LENGTH_SHORT).show();
                tv.append(targetMac + " : 设备连接已断开 \n\n");
                tv.append("================================\n\n");
                //if(toNext <= -1 || toNext >= 2) {
                    cursor++;
                    toNext = 0;
                    if(cursor < macList.size()) {
                        targetMac = macList.get(cursor);
//                        new Handler().postDelayed(new Runnable() {
//                            @Override
//                            public void run() {
//                                mBluetoothLeService.connect(targetMac);
//                                tv.append(targetMac + " : 正在连接设备。。。\n");
//                            }
//                        }, 1500);
                        try {
                            Thread.sleep(1500);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        mBluetoothLeService.connect(targetMac);
                        tv.append(targetMac + " : 正在连接设备。。。\n");
                    } else {
                        Log.d("III", "cursor go through the index : cursor = " + cursor);
                        Toast.makeText(ReqActivity.this, "已遍历全部设备", Toast.LENGTH_LONG);
                        tv.append("遍历蓝牙设备结束！\n");
                        findViewById(R.id.start_process).setEnabled(true);
                        if(mBluetoothLeService != null) mBluetoothLeService.disconnect();

                        //mBluetoothLeService = null;


                    }
//                } else {
//                    toNext++;
//                    new Handler().postDelayed(new Runnable() {
//                        @Override
//                        public void run() {
//                            mBluetoothLeService.connect(targetMac);
//                            tv.append(targetMac + " : 正在连接设备。。。\n");
//                        }
//                    }, 1500);
//                }
               // invalidateOptionsMenu();
               // clearUI();

            } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
                // Show all the supported services and characteristics on the user interface.
                displayGattServices(mBluetoothLeService.getSupportedGattServices());
            } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
                //handleAtResponse(intent.getByteArrayExtra(BluetoothLeService.AT_DATA));
                byte[] data = intent.getByteArrayExtra((BluetoothLeService.AT_DATA));
                String baowen = new String(data);
                tv.append(targetMac + " : \n" + baowen + "\n\n");
                Log.d("III", "AT DATA : " + baowen);
                ////////////////////////////////
                // 以下做 AT应答判断
                // 判断通过 => 断开连接， 准备连接下一个标签
                if(baowen.contains("AT+ID")){
                    Log.d("III", "AT 请求返回正常");
                    // 断开连接； MAC +1
                    toNext = -1;

                    try {
                        Thread.sleep(1500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    mBluetoothLeService.disconnect();
                    tv.append(targetMac + " : 正在断开连接设备。。。\n");
                    // 准备连接下一个MAC地址

                }

            }

        }
    };


    // 修改设备连接的状态
    private void updateConnectionState(final String text) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Log.d("updateConState", "state change to "+ "status:" + isConnected);
                isConnected = Boolean.getBoolean(text);
            }
        });
    }

    // 起始值设置
    void init() {
        // mac 地址列表
        String[] macArr = {"F4:A7:7E:92:6E:2D", "C4:C6:D8:48:3B:19"};
        cursor = 0;
        macList = Arrays.asList(macArr);
        targetMac = macList.get(cursor);

    }

    @Override
    protected void onResume() {
        super.onResume();
        registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
//        if (mBluetoothLeService != null) {
//            final boolean result = mBluetoothLeService.connect(targetMac);
//            Log.d("DevConAct_onRes", "Connect request result = " + result);
//        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(mGattUpdateReceiver);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(mBluetoothLeService != null ) mBluetoothLeService.disconnect();
        unbindService(mServiceConnection);
        mBluetoothLeService = null;
    }


    // 创建置顶工具栏
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.connect, menu);
        if (isConnected) {
            menu.findItem(R.id.menu_connect).setVisible(false);
            menu.findItem(R.id.menu_disconnect).setVisible(true);
        } else {
            menu.findItem(R.id.menu_connect).setVisible(true);
            menu.findItem(R.id.menu_disconnect).setVisible(false);
        }
        return true;

    }

    // 工具栏按键设置
    @Override
    public boolean onOptionsItemSelected(final MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                mBluetoothLeService.disconnect();
                unbindService(mServiceConnection);
                mBluetoothLeService = null;
                onBackPressed();
                return true;
            case R.id.menu_connect: {
                mBluetoothLeService.connect(macList.get(cursor));
                return true;
            }
            case R.id.menu_disconnect: {
                mBluetoothLeService.disconnect();
                return true;
            }
        }
//        if (android.R.id.home == (item.getItemId())) {
//            onBackPressed();
//            return true;
//        }
        return super.onOptionsItemSelected(item);
    }


    // 连接上后 获取 GATT Characteristics
    private void displayGattServices(List<BluetoothGattService> gattServices) {
        if (gattServices == null) return;

        // Loops through available GATT Services.
        for (BluetoothGattService gattService : gattServices) {

            List<BluetoothGattCharacteristic> gattCharacteristics =
                    gattService.getCharacteristics();


            // Loops through available Characteristics.
            for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
                BluetoothGattCharacteristic tempCh = gattCharacteristic;
                String uuids = tempCh.getUuid().toString();

                Log.d("CHA", "'" + uuids +"'");
                if(uuids.equals(READ_UUID.toString())) {
                    //mBluetoothLeService.setReadCha(tempCh);
                    //mBluetoothLeService.readCharacteristic(tempCh);
                    readCh = tempCh;
                    mBluetoothLeService.setCharacteristicNotification(readCh,true);
                    Log.d("READ kEY", "DONE");
                }
                else if (uuids.equals(WRITE_UUID.toString())){
                    writeCh = tempCh;
                    Log.d("WRITE KEY", "DONE");
                }
            }
        }

//        new Handler().postDelayed(new Runnable() {
//            @Override
//            public void run() {
//                Log.d("AT+LED", "send led");
//                mBluetoothLeService.writeData("AT+LED=1,2\n",writeCh);
//            }
//        }, 500);

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                Log.d("AT&V", "click at&v");
                mBluetoothLeService.writeData("AT&V\n",writeCh);
            }
        },1500);



    }

    private static IntentFilter makeGattUpdateIntentFilter() {
        final IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
        intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
        return intentFilter;
    }

    private String macAddOne(String mac) {
        if (mac.length() != 17) {
            Log.d("INVALID_MAC", "device origin mac address invalid formatt");
            return null;
        }
        StringBuilder sb1 = new StringBuilder();
        for (int i = 0; i < mac.length(); i++) {
            if (':' != (mac.charAt(i)))
                sb1.append(mac.charAt(i));
        }
        long dec = Long.parseLong(sb1.toString(), 16);
        String hex = Long.toHexString(dec + 1);
        if (hex.length() != 12) {
            Log.d("INVALID_MAC", "device add 1 mac address invalid formatt");
            return null;
        }
        StringBuilder sb2 = new StringBuilder();
        for (int j = 0; j < 12; j++) {
            sb2.append(hex.charAt(j));
            if (j % 2 == 1 && j < 11)
                sb2.append(":");
        }
        String ret = sb2.toString();
        ret = ret.toUpperCase();
        return ret;
    }

}
